package com.jacobson.huobi.common

import android.text.format.DateFormat
import com.jacobson.core.widget.logger.LoggerFactory
import com.jacobson.huobi.Constants
import com.jacobson.huobi.utils.EncryptUtil
import com.jacobson.huobi.utils.SecurityHelper
import com.jacobson.huobi.utils.TokenStorageUtil
import okhttp3.Request
import java.util.*

/**
 * ================================================
 *  HTTP鉴权
 * @author Wucz on 2018/8/6 10:17
 * ================================================
 */
object HttpAuthentication {
    private const val AUTHENTICATION_HEADER_NAME = "__AUTHENTICATION_HEADER_NAME__"
    private const val TRUE: String = "__TRUE__"
    const val AUTHENTICATION_HEADER_REFRESH_TOKEN = "__AUTHENTICATION_HEADER_REFRESH_TOKEN__"
    const val AUTHENTICATION_HEADER_PASSWORD = "__AUTHENTICATION_HEADER_PASSWORD__"
    private val AUTHENTICATION_PRE = "Bearer "
    private val AUTHENTICATION_HEAD = "Authorization"
    private const val TOKENSTR = "__AUTHENTICATION_TOKEN__"

    const val HEADER: String = "$AUTHENTICATION_HEADER_NAME:$TRUE"
    const val REFRESH_TOKEN: String = "$AUTHENTICATION_HEADER_REFRESH_TOKEN:$TRUE"
    const val TOKEN: String = "$TOKENSTR:$TRUE"

    fun authentication(request: Request): Request {
        if (request.header(TOKENSTR) == TRUE) {
            var refreshToken = TokenStorageUtil.readDataByKey(Constants.REFRESH_TOKEN)
            if (!refreshToken.isNullOrEmpty()) {
//                EventBus.getDefault().post(LoginEvent(1, null))
                return addAuthenticationInfo(request, refreshToken)
            }

            return SecurityHelper.tryMember()?.let {
                // TODO
//                addAuthenticationInfo(request, it.phone, it.password, it.type)
                request
            } ?: request
        } else if (request.header(AUTHENTICATION_HEADER_NAME) == TRUE) {
            var accessToken = TokenStorageUtil.readDataByKey(Constants.ACCESS_TOKEN)
            if (!accessToken.isNullOrEmpty()) {
                return addAuthenticationInfo(request, accessToken)
            }

            return SecurityHelper.tryMember()?.let {
                // TODO
//                addAuthenticationInfo(request, it.phone, it.password, it.type)
                request
            } ?: request
        } else if (request.header(AUTHENTICATION_HEADER_REFRESH_TOKEN) == TRUE) {
            var accessToken = TokenStorageUtil.readDataByKey(Constants.ACCESS_TOKEN)
            if (!accessToken.isNullOrEmpty()) {
                return addAuthenticationInfo(request, accessToken)
            }

            return SecurityHelper.tryMember()?.let {
                // TODO
//                addAuthenticationInfo(request, it.phone, it.password, it.type)
                request
            } ?: request
        }
        var accessToken = TokenStorageUtil.readDataByKey(Constants.ACCESS_TOKEN)
        if (!accessToken.isNullOrEmpty()) {
            return addAuthenticationInfo(request, accessToken)
        }

        return SecurityHelper.tryMember()?.let {
            // TODO
//                addAuthenticationInfo(request, it.phone, it.password, it.type)
            request
        } ?: request
        return request
    }

    private fun addAuthenticationInfo(
        request: Request,
        accessToken: String,
        type: String = "1"
    ): Request {

        return request.newBuilder()
            .removeHeader(AUTHENTICATION_HEADER_NAME)
            .addHeader(AUTHENTICATION_HEAD, AUTHENTICATION_PRE + accessToken)
            .addHeader("type", type)
            .build()
    }

    private fun checkSum(password: String, nonce: String, currentTime: String): String {
        LoggerFactory.getLogger().i("checkNum: $password, $nonce, $currentTime")
        return EncryptUtil.sha1(password + nonce + currentTime).toLowerCase(Locale.getDefault())
    }

    private fun strCurrentTime(): String {
        return DateFormat.format("yyyyMMddKKmmss", System.currentTimeMillis()).toString()
    }

    private fun randomNonce(): String {
        return UUID.randomUUID().toString().replace("-", "")
    }
}
